/**
 * 此示例是通过Buffer打包并还原文件夹示例，应用场景用于物联网OTA出现解压失败的情况处理办法，来源于 智感科技面试题 java 实现
 */

let fs = require("fs");

const SOURCE_DIR = __dirname + "\\source"; //原文件夹
const COPY_DIR = __dirname + "\\copy"; //复制后的文件夹
const FILE_INFO_BUFFER = []; //读取的文件信息列表


/**
 * 递归读取文件
 * @param path w
 */
const recursionRead = (path) => {
    if (isDir(path)) {
        let files = fs.readdirSync(path);
        files.forEach((v) => {
            recursionRead(path + "\\" + v);

        })
    } else {
        let buffer = fs.readFileSync(path);
        let relativePath = path.replace(SOURCE_DIR, "");
        FILE_INFO_BUFFER.push({path: relativePath, body: buffer});
    }

}

/**
 * 判断是不是文件夹
 * @param path 路径
 * @returns {boolean} 返回结果
 */
const isDir = (path) => {
    let stats = fs.lstatSync(path);
    return stats.isDirectory() === true;
}

const startMerge = () => {


    //递归读取文件信息
    recursionRead(SOURCE_DIR);


    //将文件信息写入
    console.log(FILE_INFO_BUFFER)

    let totalLen = 32+32;

    FILE_INFO_BUFFER.forEach((value => {
        totalLen = totalLen + 32 + 32 + value.path.length + value.body.length; //nameLen 32 位 bodyLen 32 位 path 体  body体
    }))


    let offset = 0;
    let buffer = Buffer.alloc(totalLen);
    buffer.writeInt32BE(totalLen, 0);
    buffer.writeInt32BE(FILE_INFO_BUFFER.length, 32);
    offset = offset + 32+32;

    FILE_INFO_BUFFER.forEach((value => {
        buffer.writeInt32BE(value.path.length,offset)
        offset = offset + 32;
        buffer.writeInt32BE(value.body.length,offset)
        offset = offset + 32;
        buffer.write(value.path,offset)
        offset = offset + value.path.length;
        buffer.fill(value.body, offset, offset+value.body.length)
        offset = offset + value.body.length;
    }))

    console.log(buffer)

    fs.writeFileSync("./temp.bin",buffer);
}

startMerge();

